<!--
 * @description: 剧本拆分
 * @fileName: PlaySplitting
 * @author: 17076
 * @date: 2025/3/3-上午9:24
 * @version: V1.0.0
-->

<template>
  <div>
    <el-row :gutter="10">
      <el-col :span="10" :style="{ height: $baseTableHeight(-120) + 'px' }">
        <div v-if="sectionList.length > 0" class="play-card play-left">
          <template v-for="item in sectionList">
            <div
              :id="'section' + item.partId"
              :key="item.partId"
              :class="{
                'section-item': true,
                'section-item-active': item.partId === selectSectionId || item['partId'] === selectLens['partId']
              }"
              @click="handleSection(item)"
            >
              <div
                :class="{
                  'flex-row' : true,
                  'rebuild': true
                }"
              >
<!--                <span>{{ `${item['chapterNum']}-${item['partIndex']}` }}</span>-->
                <div class="flex-row" :class="{ 'disabled': (item.lensList && item.lensList.length === 0 && item['partStatus'] === '01') }" @click.stop="handleRebuild(item)">
                  <svg-icon icon-class="create_icon" />
                  <span>重新生成</span>
                </div>
              </div>
              <pre v-text="item['partInfo']" />
            </div>
          </template>
        </div>
        <el-empty v-else class="play-card" style="height: 100%" description="暂无数据" >
          <template slot="image">
            <img src="@/assets/common/empty_role.png" alt="暂无数据" />
          </template>
        </el-empty>
      </el-col>
      <el-col :span="14" :style="{ height: $baseTableHeight(-120) + 'px' }">
        <!--总体任务进度展示-->
        <div v-if="sectionList.length > 0" class="play-card" style="height: 100%">
          <div style="height: 32px;line-height: 32px">任务进度：{{ formatterTotalProgress(sectionList) }}</div>
          <div ref="partRef" class="play-right">
            <!--          <draggable v-if="lensData.length > 0" v-model="lensData" animation="400" handle=".move" :scroll="true">-->
            <template v-for="(fragment, fragmentIndex) in sectionList">
              <div v-if="fragment['lensList'].length > 0" :id="'lens' + fragment['partId']" :key="fragment.id" class="section-container">
                <div
                  v-for="(item, index) in fragment['lensList']"
                  :id="'lens' + item['id']"
                  :key="index"
                  class="lens-container"
                  @click="handleLensSelect(item)"
                >
                  <div
                    :class="[
                      'flex-column',
                      'lens-item',
                      selectSectionId === fragment.partId ? 'active' : '',
                      item['id'] === selectLens['id'] ? 'active' : ''
                    ]"
                  >
                    <p class="flex-row" style="align-items: center">
                      <svg-icon icon-class="drag" class="move" />
                      <span style="margin: 0 10px">{{ item['index'] }}</span>
                      <span>{{ item['lensName'] }}</span>
                      <span v-if="item['combining']" style="margin-left: 10px; color: #12DBFF; font-size: 14px">
                        <i class="el-icon-loading" />
                        分镜合并中，请稍等...
                      </span>
                    </p>
                    <p v-if="item['lensTimeName']">时间: {{ item['lensTimeName'] }}</p>
                    <p>景别: {{ item['shotSizeName'] }}</p>
                    <p>场景: {{ item['scenery'] }}</p>
                    <p>剧情: {{ item['plot'] }}</p>
                    <p v-if="item['dialogues'] && item['dialogues'].length > 0">对话: {{ formatterDialoguesName(item['dialogues']) }}</p>
                    <p v-if="item['playRoles'] && item['playRoles'].length > 0">角色: {{ formatterRolesName(item['playRoles']) }}</p>
                    <i
                      class="el-icon-edit"
                      title="编辑"
                      style="position: absolute; right: 95px; top: 18px; cursor: pointer"
                      @click.stop="handleEdit(item)"
                    />
                    <el-tooltip placement="top" content="向下新增">
                      <svg-icon
                        icon-class="down_add"
                        style="position: absolute; right: 70px; top: 18px; cursor: pointer"
                        @click.stop="handleAdd(item)"
                      />
                    </el-tooltip>
                    <i
                      class="el-icon-document-copy"
                      title="复制"
                      style="position: absolute; right: 45px; top: 18px; cursor: pointer"
                      @click.stop="handleCopy(item)"
                    />
                    <i
                      class="el-icon-delete"
                      title="删除"
                      style="position: absolute; right: 20px; top: 18px; cursor: pointer"
                      @click.stop="handleDelete(item)"
                    />
<!--                    <el-dropdown style="position: absolute; right: 20px; top: 18px" @command="handleCommand($event, item)">-->
<!--                      <i class="el-icon-more opera-button" />-->
<!--                      <el-dropdown-menu slot="dropdown">-->
<!--                        &lt;!&ndash;                        <el-dropdown-item icon="el-icon-edit" command="0">编辑</el-dropdown-item>&ndash;&gt;-->
<!--                        <el-dropdown-item icon="el-icon-document-copy" command="1">复制</el-dropdown-item>-->
<!--                        &lt;!&ndash;                        <el-dropdown-item icon="el-icon-circle-plus-outline" command="2">新建</el-dropdown-item>&ndash;&gt;-->
<!--                        &lt;!&ndash;                        <el-dropdown-item icon="el-icon-rank" command="3">移动至</el-dropdown-item>&ndash;&gt;-->
<!--                        <el-dropdown-item icon="el-icon-delete" command="4">删除</el-dropdown-item>-->
<!--                      </el-dropdown-menu>-->
<!--                    </el-dropdown>-->
                  </div>
                  <el-popover
                    ref="combinePop"
                    v-model="item['showCombinePop']"
                    width="200"
                    placement="bottom-end"
                    :visible-arrow="false"
                    trigger="manual"
                    popper-class="confirm-pop"
                  >
                    <confirm-pop
                      title="确定合并分镜？"
                      @onCancel="() => { $set(item, 'showCombinePop', false) }"
                      @onConfirm="handleCombine(fragment, item)"
                    />
                    <div
                      v-show="!(fragmentIndex === 0 && index === 0) && !rebuildLoadingId && !firstLoading"
                      slot="reference"
                      title="向上合并"
                      class="part-combine"
                      @click.stop="handleCombineClick(item)"
                    />
                  </el-popover>
                </div>
                <!--            <template v-else>
                  <div class="placeholder-content">
                    <img v-if="fragment['partStatus'] === '01' || fragment['partStatus'] === '00'" src="~@/assets/write/loading.gif" class="loading">
                    <div v-else-if="fragment['partStatus'] === '02'" class="liner-button">重新生成</div>
                  </div>
                </template>-->
              </div>
              <div v-if="rebuildLoadingId && rebuildLoadingId === fragment['partId'] && fragment['lensList'].length === 0" :key="fragment.id" class="flex-column rebuild-loading-content">
                <img src="~@/assets/write/loading.gif">
                <span>生成中..</span>
                <span>分镜内容正在生成，离开页面不影响</span>
              </div>
            </template>
            <div v-if="firstLoading" class="flex-row first-loading">
              <img src="~@/assets/write/loading.gif">
              <span>分镜生成中..</span>
            </div>
          </div>
        </div>
        <el-empty v-else class="play-card" style="height: 100%" description="暂无数据" >
          <template slot="image">
            <img src="@/assets/common/empty_role.png" alt="暂无数据" />
          </template>
        </el-empty>
      </el-col>
    </el-row>
    <!--编辑组境-->
    <edit-lens ref="edit" :play-id="playId" @reloadData="fetchData" />
    <!--移动组境-->
    <move-lens ref="move" :play-id="playId" @reloadData="fetchData" />
  </div>
</template>

<script>
import draggable from 'vuedraggable'
import EditLens from './EditLens.vue'
import MoveLens from './MoveLens.vue'
import {
  copyLens,
  createPlayShot,
  createPlayShotBeach, delLens,
  queryPlayShot,
  combineLens
} from '@/api/play'
import { mapActions, mapGetters } from 'vuex'

export default {
  name: 'PlaySplitting',
  components: { draggable, MoveLens, EditLens },
  props: {
    playId: {
      type: String || Number,
      default: ''
    }
  },
  data() {
    return {
      // 剧本表单
      playForm: {},
      // 校验规则
      rules: {},
      // 当前激活的段落id
      selectSectionId: 0,
      // 当前选中分镜
      selectLens: {},
      // 分镜加载完成
      loadingFinish: true,
      // 定时器
      queryTimer: null,
      // 分段列表
      sectionList: [],
      // 镜头数据
      lensData: [],
      // 重新生成的分段id
      rebuildLoadingId: null,
      // 首次加载
      firstLoading: false
    }
  },
  computed: {
    // 剧本状态
    ...mapGetters({
      playStatus: 'lens/playStatus'
    })
  },
  mounted() {
    // 查询分段数据
    this.fetchData()
    // 批量生成镜头
    this.beachGenerate()
    this.$nextTick(() => {
      if (this.$refs.partRef) {
        // 监听界面滑动
        this.$refs.partRef.addEventListener('scroll', () => {
          this.sectionList.forEach(item => {
            if (item['lensList'] && item['lensList'].length > 0) {
              item.lensList.forEach(lens => {
                this.$set(lens, 'showCombinePop', false)
              })
            }
          })
        })
      }
    })
  },
  beforeDestroy() {
    if (this.queryTimer) {
      clearInterval(this.queryTimer)
      this.queryTimer = null
    }
    if (this.$refs.partRef) {
      this.$refs.partRef.removeEventListener('scroll', null)
    }
  },
  methods: {
    ...mapActions({
      changeShowNext3: 'lens/changeShowNext3',
      setSelectLens: 'lens/setSelectLens'
    }),
    // 批量生成
    beachGenerate() {
      if (!this.playId) {
        this.$baseMessage.error('剧本不存在,请上传剧本!')
        return
      }
      createPlayShotBeach({ playId: this.playId }).then(() => {
        // 开启定时器
        this.timer()
      })
    },
    // 获取数据
    fetchData() {
      if (!this.playId) {
        this.$baseMessage.error('剧本不存在,请上传剧本!')
        return
      }
      if (!this.rebuildLoadingId) {
        this.firstLoading = true
      }
      queryPlayShot({ playId: this.playId }).then(res => {
        this.sectionList = res.data
        // 处理分镜数据
        this.handleLensData()
      }).catch(_ => {
        if (this.timer) {
          this.rebuildLoadingId = null
          this.firstLoading = false
          clearInterval(this.timer)
          this.timer = null
        }
      })
    },
    // 格式化对话显示
    formatterDialoguesName(val) {
      // 将数组中的name 字段通过逗号拼接
      return val.map(item => `${item['playRoleName']}：${item['dialogueInfo']}`).join(',')
    },
    // 格式化角色显示
    formatterRolesName(val) {
      // console.log(val, 8989)
      // 将数组中的name 字段通过逗号拼接
      return val.map(item => item ? item.name : '').join(',')
    },
    // 格式化任务进度展示
    formatterTotalProgress(val) {
      if (this.loadingFinish) {
        return '已完成'
      } else {
        const total = val.length
        const completed = val.filter(item => item['partShotStatus'] === false).length
        return `${completed}/${total}`
      }
    },
    // 处理分镜数据
    handleLensData() {
      this.isFinish()
      // 叠加数据
      this.lensData = []
      this.sectionList.forEach(item => {
        if (item['lensList']) {
          this.lensData.push(...item['lensList'])
        }
      })
    },
    // 判断是否所有镜头生成完成
    isFinish() {
      this.loadingFinish = this.sectionList.every(item => item['partShotStatus'] === false)
      // 镜头生成完成停止定时器
      if (this.loadingFinish) {
        this.changeShowNext3(true)
        this.firstLoading = false
        this.rebuildLoadingId = null
        clearInterval(this.queryTimer)
        this.queryTimer = null
      }
    },
    // 开启定时器刷新镜头是否生成完成
    timer() {
      if (this.queryTimer) {
        clearInterval(this.queryTimer)
        this.queryTimer = null
        return
      }
      this.queryTimer = setInterval(() => {
        this.fetchData()
      }, 3000)
    },
    /* // 分解镜头
    handleDisassembleLens(item) {
      createPlayShot({ partId: item.partId }).then(res => {
        console.log(res, 8989)
      })
    },*/
    // 段落切换
    handleSection(item) {
      this.selectSectionId = item.partId
      // 取消选中的分镜
      this.selectLens = {}
      // 右侧分镜滑动到对应位置
      const lensContainer = document.getElementById('lens' + item['partId'])
      if (lensContainer) {
        lensContainer.scrollIntoView({ behavior: 'smooth' })
      }
    },
    // 分镜切换
    handleLensSelect(item) {
      this.selectLens = item
      // 取消段落选中的id
      this.selectSectionId = 0
      // 左侧分段滑动到对应位置
      const sectionContainer = document.getElementById('section' + item['partId'])
      if (sectionContainer) {
        sectionContainer.scrollIntoView({ behavior: 'smooth' })
      }
    },
    // 重新生成
    handleRebuild(item) {
      this.$baseConfirm('确定将该段重新生成分镜头吗？', '提示', async() => {
        // 将该段的镜头删除
        item['lensList'] = []
        // this.$set(item, 'lensList', [])
        // 将该段的状态设置为未生成
        item['partShotStatus'] = true
        // this.$set(item, 'partShotStatus', true)
        // 格式化任务进度展示
        this.formatterTotalProgress(this.sectionList)
        // 重新生成
        this.rebuildLoadingId = item.partId
        const { code, msg } = await createPlayShot({ partId: item.partId, playId: this.playId })
        code === 200 ? this.$baseMessage.success(msg || '重新生成成功!') : this.$baseMessage.error(msg || '重新生成失败!')
        if (code !== 200) {
          this.rebuildLoadingId = null
          return
        }
        // 刷新数据
        this.fetchData()
        // 开启定时器
        this.timer()
      })
    },
    // 向上合并按钮点击
    handleCombineClick(item) {
      // 判断如果存在已经正在合并的数据,则不显示
      const lensList = this.sectionList.flatMap(item => item.lensList)
      if (lensList.some(lens => lens['combining'])) {
        this.$baseMessage.warning('当前存在分镜正在合并中，请稍后再试!')
        return
      }
      this.$set(item, 'showCombinePop', true)
    },
    // 向上合并
    async handleCombine(item, subItem) {
      // 当前条目的id
      const currentId = subItem.id
      // 将二维数转为一维数组
      const lensList = this.sectionList.flatMap(item => item.lensList)
      const parentIndex = lensList.findIndex(section => section.id === currentId)
      const prevIndex = parentIndex - 1
      const lastId = lensList[prevIndex]['id']
      // const loading = this.$baseLoading(0, '分镜合并中，请稍等')
      // 当当前要合并的分镜设置合并中的状态
      this.$set(subItem, 'combining', true)
      this.$set(lensList[prevIndex], 'combining', true)
      this.$set(subItem, 'showCombinePop', false)
      const { code, msg } = await combineLens({ upLensId: lastId, currentLensId: currentId, playId: this.playId })
      // loading.close()
      if (code === 200) {
        // 清空选中的分镜
        await this.setSelectLens(null)
        this.$baseMessage.success(msg || '合并成功!')
        this.fetchData()
      } else {
        this.$baseMessage.error(msg || '合并失败!')
      }
    },
    // 菜单点击
    handleCommand(type, item) {
      // 如果当前正在生成中,不可操作
      if (this.rebuildLoadingId || this.firstLoading) {
        this.$baseMessage.warning('当前存在分镜正在生成中,不可操作!')
        return
      }
      switch (type) {
        case '0':
          this.handleEdit(item)
          break
        case '1':
          this.handleCopy(item)
          break
        case '2':
          this.handleAdd(item)
          break
        case '3':
          this.handleMoveTo(item)
          break
        case '4':
          this.handleDelete(item)
          break
      }
    },
    // 编辑
    handleEdit(item) {
      this.$refs.edit.show(item, true)
    },
    // 复制
    handleCopy(item) {
      this.$baseConfirm('确定复制该组镜头吗？复制的镜头会显示到该镜头下面', '提示', async() => {
        const { code, msg } = await copyLens({ ...item, dialogues: [] })
        code === 200 ? this.$baseMessage.success(msg || '复制成功!') : this.$baseMessage.error(msg || '复制成功!')
        // 清空选中的分镜
        await this.setSelectLens(null)
        this.fetchData()
      })
    },
    // 新建
    handleAdd(item) {
      this.$refs.edit.show(item, false)
    },
    // 移动至
    handleMoveTo(item) {
      this.$refs.move.show(item)
    },
    // 删除
    handleDelete(item) {
      this.$baseConfirm('确定删除该组镜头吗？', '提示', async() => {
        const { code, msg } = await delLens(item['id'])
        code === 200 ? this.$baseMessage.success(msg || '删除成功!') : this.$baseMessage.error(msg || '删除失败!')
        // 清空选中的分镜
        await this.setSelectLens(null)
        this.fetchData()
      })
    }
  }
}
</script>

<style scoped lang="scss">
.play-card {
  background: $base-content-background;
  border-radius: 8px;
  padding: 20px;
  box-sizing: border-box;
  margin-top: 10px;
  color: #FFFFFF;
}
.play-left {
  height: 100%;
  overflow-y: auto;
  .section-item {
    position: relative;
    padding: 10px;
    box-sizing: border-box;
    border-radius: 8px;
    border: 1px solid #39414E;
    background: #272C36;
    margin-bottom: 10px;
    .rebuild {
      font-size: 12px;
      justify-content: flex-end;
      >div {
        color: $base-color-default;
        span {
          margin-left: 5px;
        }
        &.disabled {
          cursor: not-allowed;
          color: #B6C7D1;
        }
      }
    }
    pre {
      line-height: 30px;
      white-space: pre-wrap;
      word-break: break-all;
    }
    &:hover {
      cursor: pointer;
      //border-color: $base-color-default;
    }
    &-active {
      border-color: $base-color-default;
    }
  }
}
.play-right {
  height: calc(100% - 32px);
  background: $base-content-background;
  overflow-y: auto;
  .first-loading {
    font-size: 13px;
    margin-top: 20px;
    align-items: center;
    img {
      width: 40px;
      height: 40px;
    }
    span {
      margin-left: 5px;
    }
  }
  .rebuild-loading-content {
    align-items: center;
    background: #272C36;
    border: 1px solid #39414E;
    padding: 10px;
    box-sizing: border-box;
    margin: 10px 0;
    width: calc(100% - 50px);
    border-radius: 8px;
    img {
      width: 40px;
      height: 40px;
    }
    span {
      margin-top: 5px;
      font-size: 12px;
      color: #B6C7D1;
    }
    span:nth-child(2) {
      font-size: 16px;
      color: #FFFFFF;
      font-weight: bold;
    }
  }
  .placeholder-content {
    background: #272C36;
    border: 1px solid #39414E;
    padding: 10px;
    box-sizing: border-box;
    margin-bottom: 10px;
    border-radius: 8px;
    text-align: center;
  }
  .section-container {
    .lens-container {
      position: relative;
      .lens-item {
        background: #272C36;
        color: $base-color-white;
        margin-top: 10px;
        border: 1px solid #39414E;
        border-radius: 8px;
        padding: 8px 12px;
        box-sizing: border-box;
        position: relative;
        width: calc(100% - 50px);
        //&:hover {
        //  border-color: $base-color-default;
        //}
        &.active {
          border-color: $base-color-default;
        }
        //.svg-icon {
        //  cursor: move;
        //}
        .opera-button {
          cursor: pointer;
          color: #FFFFFF;
        }
        >p {
          margin: 0;
          margin-bottom: 8px;
          line-height: 20px;
        }
      }
      .part-combine {
        position: absolute;
        right: 0;
        top: -44px;
        width: 48px;
        height: 76px;
        background: url("~@/assets/write/paragraph-combine.png") no-repeat;
        background-size: 100% 100%;
        cursor: pointer;
        display: none;
      }
      &:hover {
        .part-combine {
          display: block;
        }
      }
    }
    &:first-child {
      .lens-container:first-child {
        &:hover {
          .part-combine {
            display: none;
          }
        }
      }
    }
  }
  .loading {
    width: 80px;
    height: 80px;
    margin: 0 auto;
  }
}
</style>
